package com.pxl.springbootinit.config;

import com.pxl.springbootinit.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;

@Configuration
@Slf4j
public class ThreadPoolExecutorConfig {
    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        // 创建一个线程工厂
        ThreadFactory threadFactory = new ThreadFactory() {
            // 初始化线程数为 1
            private int count = 1;

            @Override
            // 每当线程池需要创建新线程时，就会调用newThread方法
            // @NotNull Runnable r 表示方法参数 r 应该永远不为null，
            // 如果这个方法被调用的时候传递了一个null参数，就会报错
            public Thread newThread(@NotNull Runnable r) {
                // 创建一个新的线程
                Thread thread = new Thread(r);
                // 给新线程设置一个名称，名称中包含线程数的当前值
                thread.setName("IO操作线程" + count);
                // 线程数递增
                count++;
                // 返回新创建的线程
                return thread;
            }
        };
        // 创建一个拒绝执行处理器
        ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor(threadFactory);
        // 返回创建的线程池
        return threadPoolExecutor;
    }

    @NotNull
    private static ThreadPoolExecutor getThreadPoolExecutor(ThreadFactory threadFactory) {
        // 创建一个新的线程池，线程池核心大小为CPU核心数/2，最大线程数为CPU核心数*2，
        // 非核心线程空闲时间为100秒，任务队列为阻塞队列，长度为12，使用自定义的线程工厂创建线程
        // 拒绝策略为当前运行线程来执行
        int nowCPUTotalNums = Runtime.getRuntime().availableProcessors();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(nowCPUTotalNums/2, nowCPUTotalNums*2, 100, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(12), threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
        return threadPoolExecutor;
    }
}